/* eslint-disable no-unused-vars */
const path = require('path');
const fs = require('fs-extra');
const chalk = require('chalk');
const { rename, distinct } = require('./utils/distinct');
const {
  isObValidate,
  getFinalTypeCase,
  getTypeCase,
  upperCamelCase,
  isEmptyObject
} = require('./utils/utils');
const {
  handleConvert,
  handleCreator,
  coveringTreatment
} = require('./utils/index');

let existStore = null;
let alphaContext = '';
const template = './template/index.hbs';
const source = fs.readFileSync(path.resolve(__dirname, template), 'utf-8');

function logSignWarn (key) {
  console.log(chalk.yellow(`Log: 属性名${key}含$符号，现已跳过该属性`));
}

function classCreator (nameClass, ableGenerateValue) {
  alphaContext += handleCreator(source, nameClass, ableGenerateValue) + '\r\n';
}

function paramTravel (key, list = [], nameClass) {
  let allowed = 0;
  let literal = 'dynamic';

  const __ob__ = Object.create(null);
  for (const parameter of list) {
    ++allowed;
    literal = getTypeCase(parameter);

    if (literal === 'object' && allowed <= 12) {
      coveringTreatment(__ob__, parameter);
    }
  }

  if (Object.keys(__ob__).length) {
    travel(handleConvert(__ob__), upperCamelCase(key), nameClass);
    literal = rename(upperCamelCase(key), nameClass);
  }

  if (key.startsWith('?')) {
    return `List<${literal}>? ${key.replace('?', '')}`;
  } else {
    return `List<${literal}> ${key}`;
  }
}

function travel (convert, nameClass = 'AutoGenerateAlpha', parent = '') {
  if (convert == null) return;

  const listAtDerators = [];
  const listAtParameters = [];

  for (const key in convert) {
    const __ob__ = convert[key];
    let decoration = '';
    // 过滤掉含$符号的属性，直接跳过，不做处理
    if (__ob__ && key.includes('$')) {
      logSignWarn(key);
      continue;
    }
    // 过滤处理空对象（排除空数组），针对空对象直接跳过
    if (__ob__ && isEmptyObject(__ob__)) continue;
    listAtParameters.push(key.replace('?', ''));

    if (Array.isArray(__ob__)) {
      decoration = paramTravel(key, __ob__, nameClass);
    } else {
      if (__ob__ && isObValidate(__ob__)) {
        const keyClass = travel(__ob__, upperCamelCase(key), nameClass);
        decoration = getFinalTypeCase(key, __ob__, keyClass);
      } else {
        decoration = getFinalTypeCase(key, __ob__);
      }
    }

    listAtDerators.push(decoration);
  }

  return distinct(existStore, nameClass, parent, listAtParameters, listAtDerators);
}

function alphaGenerate (json = {}, nameClass = 'AutoGenerateAlpha') {
  alphaContext = '';

  if (Object.keys(json).length) {
    existStore = new Map();
    travel(json, nameClass);
    for (const [nameClass, value] of existStore) {
      classCreator(nameClass, value);
    }

    existStore = null;
    return alphaContext;
  } else {
    return alphaContext;
  }
}

module.exports = alphaGenerate;
